using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SBPweb.Themes.Windows.Skins;
using SBPweb.Themes.Windows;

namespace SBPweb.Controls.Windows.Bar
{
	/// <summary>
	/// Class of ToolStripMixer
	/// </summary>
	[ToolboxBitmap(typeof(System.Windows.Forms.TrackBar))]
	public partial class ToolStripMixer : ToolStripItem, ISkinnable
	{
		#region Private members

		private ToolStripMixerStyle mMixerStyle = ToolStripMixerStyle.Trackbar;

		private Skin mSkin;
		private bool mUseDefaultSkin = true;

		private double mLastInputPosition;
		private Rectangle mInputClipRect;
		private Point mInputClipRectMidPoint;
		private double mLastOutputPosition;
		private Rectangle mOutputClipRect;
		private Point mOutputClipRectMidPoint;

		private Color mMaxColor = Color.Green;
		private Color mMuteColor = Color.Red;

		private Point mMouseDownLocation;

		private double mInputPosition = 60.0;
		private bool mInputEnabled = true;
		private double mOutputPosition = 50.0;
		private bool mOutputEnabled = true;

		private Rectangle mInputTrackThumbRect;
		private Rectangle mOutputTrackThumbRect;

//		private ITelephonyService mTelephonyService;

		#endregion

		#region Constructor logic

		/// <summary>
		/// Constructor of ToolStripMixer
		/// </summary>
		public ToolStripMixer()
		{
			InitializeComponent();
		}

		#endregion

		#region Properties

		/// <summary>
		/// Input position
		/// </summary>
		public double InputPosition
		{
			get
			{
				return mInputPosition;
			}
			set
			{
				if (value < 0)
				{
					value = 0;
				}
				if (value > 100)
				{
					value = 100;
				}
				mInputPosition = value;
			}
		}

		/// <summary>
		/// Output position
		/// </summary>
		public double OutputPosition
		{
			get
			{
				return mOutputPosition;
			}
			set
			{
				if (value < 0)
				{
					value = 0;
				}
				if (value > 100)
				{
					value = 100;
				}
				mOutputPosition = value;
			}
		}

		/// <summary>
		/// Max color
		/// </summary>
		public Color MaxColor
		{
			get
			{
				return mMaxColor;
			}
			set
			{
				mMaxColor = value;
			}
		}

		/// <summary>
		/// Mute color
		/// </summary>
		public Color MuteColor
		{
			get
			{
				return mMuteColor;
			}
			set
			{
				mMuteColor = value;
			}
		}

		/// <summary>
		/// Is input enabled?
		/// </summary>
		public bool InputEnabled
		{
			get
			{
				return mInputEnabled;
			}
			set
			{
				mInputEnabled = value;
			}
		}

		/// <summary>
		/// Is output enabled?
		/// </summary>
		public bool OutputEnabled
		{
			get
			{
				return mOutputEnabled;
			}
			set
			{
				mOutputEnabled = value;
			}
		}

		/// <summary>
		/// Style of mixer
		/// </summary>
		public ToolStripMixerStyle MixerStyle
		{
			get
			{
				return mMixerStyle;
			}
			set
			{
				mMixerStyle = value;
			}
		}

		#endregion

		#region Custom draw

		/// <summary>
		/// Raises when the mouse button was clicked down
		/// </summary>
		/// <param name="e">event args</param>
		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);

			switch (e.Button)
			{
				case MouseButtons.Left:

					mMouseDownLocation = e.Location;
					mLastInputPosition = InputPosition;
					mLastOutputPosition = OutputPosition;

					break;

				case MouseButtons.Right:

					if (mInputClipRect.Contains(e.Location))
					{
						InputEnabled = !InputEnabled;
					}

					if (mOutputClipRect.Contains(e.Location))
					{
						OutputEnabled = !OutputEnabled;
					}

					Invalidate();

					break;
			}
		}

		/// <summary>
		/// Raises when the mouse moved
		/// </summary>
		/// <param name="mea">event args</param>
		protected override void OnMouseMove(MouseEventArgs mea)
		{
			base.OnMouseMove(mea);

			switch (MixerStyle)
			{
				case ToolStripMixerStyle.Knob:
					if (mea.Button == MouseButtons.Left)
					{
						int deltaY = mMouseDownLocation.Y - mea.Y;

						if (mInputClipRect.Contains(mMouseDownLocation) && InputEnabled)
						{
							InputPosition = mLastInputPosition + deltaY * 4.0;
						}

						if (mOutputClipRect.Contains(mMouseDownLocation) && OutputEnabled)
						{
							OutputPosition = mLastOutputPosition + deltaY * 4.0;
						}
					}
					break;
				case ToolStripMixerStyle.Trackbar:
				default:
					if (mea.Button == MouseButtons.Left)
					{
						int deltaX = mea.X - mMouseDownLocation.X;

						if (mInputClipRect.Contains(mMouseDownLocation) && InputEnabled)
						{
							InputPosition = mLastInputPosition + deltaX * 100 / mInputClipRect.Width - 8;
						}

						if (mOutputClipRect.Contains(mMouseDownLocation) && OutputEnabled)
						{
							OutputPosition = mLastOutputPosition + deltaX * 100 / mOutputClipRect.Width - 8;
						}
					}
					break;
			}

			Invalidate();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="pe"></param>
		protected override void OnPaint(PaintEventArgs pe)
		{
			base.OnPaint(pe);

			Rectangle clipRect = pe.ClipRectangle;

			Brush darkerBrush = Brushes.Black;
			Brush darkBrush = Brushes.Gray;
			Brush lightBrush = Brushes.DarkGray;

			if (Skin != null)
			{
				darkerBrush = new SolidBrush(Skin.CachedProperties.ControlTextColor);
				darkBrush = new SolidBrush(Skin.CachedProperties.ControlDisabledTextColor);
				lightBrush = new SolidBrush(Skin.CachedProperties.ControlDisabledColor);
			}

			pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

			int midX = Convert.ToInt32(Math.Round((double)(clipRect.Right - clipRect.Left) / 2));
			int midY = Convert.ToInt32(Math.Round((double)(clipRect.Bottom - clipRect.Top) / 2));

			int inPos1 = Convert.ToInt32(Math.Round((double)InputPosition / 100 * 255));
			int inPos2 = Convert.ToInt32(Math.Round((double)InputPosition / 100 * 280));
			int outPos1 = Convert.ToInt32(Math.Round((double)OutputPosition / 100 * 255));
			int outPos2 = Convert.ToInt32(Math.Round((double)OutputPosition / 100 * 280));

			Brush inBrush;
			Brush outBrush;
			if (InputEnabled)
			{
				inBrush = new SolidBrush(Color.FromArgb(inPos1, MaxColor));
			}
			else
			{
				inBrush = new SolidBrush(MuteColor);
			}

			if (OutputEnabled)
			{
				outBrush = new SolidBrush(Color.FromArgb(outPos1, MaxColor));
			}
			else
			{
				outBrush = new SolidBrush(MuteColor);
			}

			string inText = InputPosition.ToString();
			string outText = OutputPosition.ToString();

			if (!InputEnabled)
			{
				inText = "0";
			}
			if (!OutputEnabled)
			{
				outText = "0";
			}

			StringFormat sf = new StringFormat(StringFormat.GenericDefault);
			SizeF size;
			pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

			switch (MixerStyle)
			{
				#region Draw knob
				case ToolStripMixerStyle.Knob:
					{

						float inStartAngle = 120 + inPos2;
						float inSweepAngle = 10;
						float outStartAngle = 120 + outPos2;
						float outSweepAngle = 10;

						mInputClipRect = new Rectangle(clipRect.Left, 0, clipRect.Height - 1, clipRect.Height - 1);

						pe.Graphics.FillPie(darkerBrush, mInputClipRect.X - 2, mInputClipRect.Y - 2, mInputClipRect.Width + 4, mInputClipRect.Height + 4, 120, 5);
						pe.Graphics.FillPie(darkerBrush, mInputClipRect.X - 2, mInputClipRect.Y - 2, mInputClipRect.Width + 4, mInputClipRect.Height + 4, 55, 5);
						pe.Graphics.FillEllipse(darkerBrush, mInputClipRect);
						pe.Graphics.FillEllipse(darkBrush, mInputClipRect.X + 1, mInputClipRect.Y + 1, mInputClipRect.Width - 2, mInputClipRect.Height - 2);
						if (InputEnabled)
						{
							pe.Graphics.FillPie(darkerBrush, mInputClipRect.X + 1, mInputClipRect.Y + 1, mInputClipRect.Width - 4, mInputClipRect.Height - 2, inStartAngle, inSweepAngle);
						}
						pe.Graphics.FillEllipse(lightBrush, mInputClipRect.X + 5, mInputClipRect.Y + 5, mInputClipRect.Width - 10, mInputClipRect.Height - 10);
						pe.Graphics.FillEllipse(inBrush, mInputClipRect.X + 6, mInputClipRect.Y + 6, mInputClipRect.Width - 12, mInputClipRect.Height - 12);

						mInputClipRectMidPoint = new Point(mInputClipRect.X + mInputClipRect.Width / 2, mInputClipRect.Y + mInputClipRect.Height / 2);

						mOutputClipRect = new Rectangle(clipRect.Right - clipRect.Height - 1, 0, clipRect.Height - 1, clipRect.Height - 1);

						pe.Graphics.FillPie(darkerBrush, mOutputClipRect.X - 2, mOutputClipRect.Y - 2, mOutputClipRect.Width + 4, mOutputClipRect.Height + 4, 120, 5);
						pe.Graphics.FillPie(darkerBrush, mOutputClipRect.X - 2, mOutputClipRect.Y - 2, mOutputClipRect.Width + 4, mOutputClipRect.Height + 4, 55, 5);
						pe.Graphics.FillEllipse(darkerBrush, mOutputClipRect);
						pe.Graphics.FillEllipse(darkBrush, mOutputClipRect.X + 1, mOutputClipRect.Y + 1, mOutputClipRect.Width - 2, mOutputClipRect.Height - 2);
						if (OutputEnabled)
						{
							pe.Graphics.FillPie(darkerBrush, mOutputClipRect.X + 1, mOutputClipRect.Y + 1, mOutputClipRect.Width - 4, mOutputClipRect.Height - 2, outStartAngle, outSweepAngle);
						}
						pe.Graphics.FillEllipse(lightBrush, mOutputClipRect.X + 5, mOutputClipRect.Y + 5, mOutputClipRect.Width - 10, mOutputClipRect.Height - 10);
						pe.Graphics.FillEllipse(outBrush, mOutputClipRect.X + 6, mOutputClipRect.Y + 6, mOutputClipRect.Width - 12, mOutputClipRect.Height - 12);

						mOutputClipRectMidPoint = new Point(mOutputClipRect.X + mOutputClipRect.Width / 2, mOutputClipRect.Y + mOutputClipRect.Height / 2);

						pe.Graphics.DrawImage(global::SBPweb.Controls.Windows.Properties.Resources.Designer_Button_64x64, mInputClipRect);
						pe.Graphics.DrawImage(global::SBPweb.Controls.Windows.Properties.Resources.Designer_Button_64x64, mOutputClipRect);

						size = pe.Graphics.MeasureString(inText, this.Font, new SizeF(mInputClipRect.Width, mInputClipRect.Height), sf);
						pe.Graphics.DrawString(inText, this.Font, darkerBrush, mInputClipRectMidPoint.X - size.Width / 2 + 1, mInputClipRectMidPoint.Y - size.Height / 2 + 1);
						size = pe.Graphics.MeasureString(outText, this.Font, new SizeF(mOutputClipRect.Width, mOutputClipRect.Height), sf);
						pe.Graphics.DrawString(outText, this.Font, darkerBrush, mOutputClipRectMidPoint.X - size.Width / 2 + 1, mOutputClipRectMidPoint.Y - size.Height / 2 + 1);

						pe.Graphics.DrawString("in", new Font(this.Font.FontFamily, 5.0F), darkerBrush, mInputClipRect.Right, mInputClipRect.Bottom - 7);
						pe.Graphics.DrawString("out", new Font(this.Font.FontFamily, 5.0F), darkerBrush, mOutputClipRect.Left - 10, mInputClipRect.Bottom - 7);
					}
					break;
				#endregion

				#region Draw trackbar
				case ToolStripMixerStyle.Trackbar:
				default:
					{
						#region Input

						mInputClipRect = new Rectangle(clipRect.Left + 14 , 8, clipRect.Width - 36, midY - 8);

						List<Point> inPoints = new List<Point>();

						inPoints.Add(new Point(mInputClipRect.Left - 2, mInputClipRect.Top - 2));
						inPoints.Add(new Point(mInputClipRect.Right + 2, mInputClipRect.Top - 2));
						inPoints.Add(new Point(mInputClipRect.Right + 2, mInputClipRect.Top));
						inPoints.Add(new Point(mInputClipRect.Right, mInputClipRect.Top));
						inPoints.Add(new Point(mInputClipRect.Left, mInputClipRect.Bottom));
						inPoints.Add(new Point(mInputClipRect.Right, mInputClipRect.Bottom));
						inPoints.Add(new Point(mInputClipRect.Right, mInputClipRect.Top));
						inPoints.Add(new Point(mInputClipRect.Right + 2, mInputClipRect.Top));
						inPoints.Add(new Point(mInputClipRect.Right + 2, mInputClipRect.Bottom + 2));
						inPoints.Add(new Point(mInputClipRect.Left - 2, mInputClipRect.Bottom + 2));

						pe.Graphics.FillRectangle(darkerBrush, new Rectangle(mInputClipRect.Left - 2, mInputClipRect.Top - 2, mInputClipRect.Width + 4, mInputClipRect.Height + 4));
						pe.Graphics.FillRectangle(Brushes.White, mInputClipRect);
						pe.Graphics.FillRectangle(inBrush, mInputClipRect);
						pe.Graphics.FillPolygon(lightBrush, inPoints.ToArray());

						int inPos3 = Convert.ToInt32(Math.Round((double)InputPosition / 100 * mInputClipRect.Width - 8));

						mInputTrackThumbRect = new Rectangle(mInputClipRect.Left + inPos3, mInputClipRect.Top - 2, (int)((mInputClipRect.Height + 4) * 1.2), mInputClipRect.Height + 4);

						pe.Graphics.DrawImage(global::SBPweb.Controls.Windows.Properties.Resources.Designer_Button_64x64, mInputTrackThumbRect);
						pe.Graphics.DrawString("in", new Font(this.Font.FontFamily, 5.0F), darkerBrush, mInputClipRect.Left - 14, mInputClipRect.Bottom - 7);

						size = pe.Graphics.MeasureString(inText, this.Font, new SizeF(mInputClipRect.Width, mInputClipRect.Height), sf);
						pe.Graphics.DrawString(inText, this.Font, darkerBrush, mInputClipRect.Right + 2, mInputClipRect.Bottom - size.Height - 3);

						#endregion

						#region Output

						mOutputClipRect = new Rectangle(clipRect.Left + 14, midY + 4, clipRect.Width - 36, midY - 8);

						List<Point> outPoints = new List<Point>();

						outPoints.Add(new Point(mOutputClipRect.Left - 2, mOutputClipRect.Top - 2));
						outPoints.Add(new Point(mOutputClipRect.Right + 2, mOutputClipRect.Top - 2));
						outPoints.Add(new Point(mOutputClipRect.Right + 2, mOutputClipRect.Top));
						outPoints.Add(new Point(mOutputClipRect.Right, mOutputClipRect.Top));
						outPoints.Add(new Point(mOutputClipRect.Left, mOutputClipRect.Bottom));
						outPoints.Add(new Point(mOutputClipRect.Right, mOutputClipRect.Bottom));
						outPoints.Add(new Point(mOutputClipRect.Right, mOutputClipRect.Top));
						outPoints.Add(new Point(mOutputClipRect.Right + 2, mOutputClipRect.Top));
						outPoints.Add(new Point(mOutputClipRect.Right + 2, mOutputClipRect.Bottom + 2));
						outPoints.Add(new Point(mOutputClipRect.Left - 2, mOutputClipRect.Bottom + 2));

						pe.Graphics.FillRectangle(darkerBrush, new Rectangle(mOutputClipRect.Left - 2, mOutputClipRect.Top - 2, mOutputClipRect.Width + 4, mOutputClipRect.Height + 4));
						pe.Graphics.FillRectangle(Brushes.White, mOutputClipRect);
						pe.Graphics.FillRectangle(outBrush, mOutputClipRect);
						pe.Graphics.FillPolygon(lightBrush, outPoints.ToArray());

						int outPos3 = Convert.ToInt32(Math.Round((double)OutputPosition / 100 * mOutputClipRect.Width - 8));

						mOutputTrackThumbRect = new Rectangle(mOutputClipRect.Left + outPos3, mOutputClipRect.Top - 2, (int)((mOutputClipRect.Height + 4) * 1.2), mOutputClipRect.Height + 4);

						pe.Graphics.DrawImage(global::SBPweb.Controls.Windows.Properties.Resources.Designer_Button_64x64, mOutputTrackThumbRect);
						pe.Graphics.DrawString("out", new Font(this.Font.FontFamily, 5.0F), darkerBrush, mOutputClipRect.Left - 14, mOutputClipRect.Bottom - 7);

						size = pe.Graphics.MeasureString(outText, this.Font, new SizeF(mOutputClipRect.Width, mOutputClipRect.Height), sf);
						pe.Graphics.DrawString(outText, this.Font, darkerBrush, mOutputClipRect.Right + 2, mOutputClipRect.Bottom - size.Height - 3);

						#endregion
					}
					break;
				#endregion
			}
		}

		#endregion

		#region ISkinnable Members

		/// <summary>
		/// Use default skin?
		/// </summary>
		[Category("Look && feel")]
		public bool UseDefaultSkin
		{
			get
			{
				return mUseDefaultSkin;
			}
			set
			{
				mUseDefaultSkin = value;
				Invalidate();
			}
		}

		/// <summary>
		/// Used skin
		/// </summary>
		[Category("Look && feel")]
		public Skin Skin
		{
			get
			{
				if (this.UseDefaultSkin)
				{
					return DefaultLookAndFeel.Skin;
				}

				return mSkin;
			}
			set
			{
				mSkin = value;
				Invalidate();
			}
		}

		#endregion

		/// <summary>
		/// Enum of ToolStripMixerStyle
		/// </summary>
		public enum ToolStripMixerStyle
		{
			/// <summary>
			/// Knob style
			/// </summary>
			Knob,
			/// <summary>
			/// Trackbar style
			/// </summary>
			Trackbar
		}
	}
}
